package top.csjss.hospital.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.csjss.hospital.dto.CashierDTO;
import top.csjss.hospital.entity.Cashier;
import top.csjss.hospital.entity.CashierExample;
import top.csjss.hospital.entity.Pharmacy;
import top.csjss.hospital.entity.PharmacyExample;
import top.csjss.hospital.enums.HospitalExceptionEnums;
import top.csjss.hospital.exception.HospitalException;
import top.csjss.hospital.mapper.CashierMapper;
import top.csjss.hospital.mapper.PharmacyMapper;
import top.csjss.hospital.service.CashierService;
import top.csjss.hospital.service.OutPatientTypeService;
import top.csjss.hospital.service.PharmacyService;
import top.csjss.hospital.vo.CashierVO;
import top.csjss.hospital.vo.R;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author ztf
 * @Date 16:45 2021/10/21
 **/
@Service
public class CashierServiceImpl implements CashierService {
    private Logger log = LoggerFactory.getLogger(CashierServiceImpl.class);

    @Autowired
    private CashierMapper cashierMapper;
    @Autowired
    private PharmacyMapper pharmacyMapper;
    @Autowired
    private OutPatientTypeService outPatientTypeService;
    @Autowired
    private PharmacyService pharmacyService;

    @Override
    public Integer selectUnpaidDrugs(Integer reportId) {
        //封装查询数据
        CashierExample example = new CashierExample();
        CashierExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reportId);
        criteria.andStateEqualTo(0);
        List<Cashier> cashiers = cashierMapper.selectByExample(example);
        List<Integer> list = new ArrayList<>();
        for (Cashier cashier : cashiers) {
            list.add(cashier.getState());
        }
        //判断
        for (Integer mstate : list) {
            if (mstate == 0) {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public List<CashierVO> selectDrugCashierInformation(Integer perid, Integer page, Integer limit) {
        //开启分页
        PageHelper.startPage(page, limit);
        //查询
        //封装查询条件
        CashierExample example = new CashierExample();
        CashierExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(perid);
        List<Cashier> cashiers = cashierMapper.selectByExample(example);
        //封装查询结果
        List<CashierVO> data = new ArrayList<>();
        for (Cashier cashier : cashiers) {
            CashierVO vo = new CashierVO(cashier.getCashierId(), cashier.getDrugName(), cashier.getDrugNum(), cashier.getRepicePrice(), cashier.getRepiceTotal(), cashier.getOstate(),cashier.getState());
            data.add(vo);
        }
        return data;
    }

    @Override
    public Integer selectUnpaidProject(Integer reportId) {
        CashierExample example = new CashierExample();
        CashierExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reportId);
        criteria.andStateEqualTo(1);
        List<Cashier> cashiers = cashierMapper.selectByExample(example);
        List<Integer> list = new ArrayList<>();
        for (Cashier cashier : cashiers) {
            list.add(cashier.getMstate());
        }
        for (Integer mstate : list) {
            if (mstate == 0) {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public Integer selectOutstandingProjects(Integer reportId) {
        //封装查询条件
        CashierExample example = new CashierExample();
        CashierExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reportId);
        criteria.andStateEqualTo(1);
        criteria.andMstateEqualTo(1);
        criteria.andJieEqualTo("");
        //查询
        List<Cashier> cashiers = cashierMapper.selectByExample(example);
        //判断
        for (Cashier cashier : cashiers) {
            if (cashier != null) {
                return 1;
            }
        }
        return 0;
    }

    @Override
    public Integer selectPrescriptionDrugsByCurrentPatient(Integer reid, String mename) {

        CashierExample example = new CashierExample();
        CashierExample.Criteria criteria = example.createCriteria();
        criteria.andReportIdEqualTo(reid);
        criteria.andDrugNameEqualTo(mename);
        criteria.andMstateEqualTo(0);
        long count = cashierMapper.countByExample(example);

        if (count != 0) {
            return 1;
        }
        return 0;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void addPrescription(Integer registerId, String name, Integer num) {
        Integer count = null;
        //1. 查询当前药品的库存数量，（可以开启悲观锁，但是主要索引是否生效问题）
        //未开锁
        PharmacyExample pharmacyExample = new PharmacyExample();
        PharmacyExample.Criteria pharmacyCriteria = pharmacyExample.createCriteria();
        pharmacyCriteria.andPharmacyNameEqualTo(name);
        List<Pharmacy> pharmacies = pharmacyMapper.selectByExample(pharmacyExample);
        if (pharmacies.size() == 0 || pharmacies == null) {
            log.info("【添加-修改处方】失败未查询到该药品");
            throw new HospitalException(HospitalExceptionEnums.CAO_ADD_PRESCRIPTION);
        }
        Integer drugStoreNum = pharmacies.get(0).getDrugStoreNum();


        //2. 判断药品库存数是否充足
        if (num > drugStoreNum) {
            log.info("【添加处方信息】药品不足");
            throw new HospitalException(HospitalExceptionEnums.CAO_ADD_PRESCRIPTION);
        }


        //3. 扣减药品的库存数
        Pharmacy pharmacy = new Pharmacy();
        pharmacy.setDrugStoreNum(drugStoreNum - num);
        pharmacyMapper.updateByExampleSelective(pharmacy, pharmacyExample);

        //4. 查询药品单价，计算总价
        Double totalPrice = null;
        if (pharmacies.size() == 1) {
            totalPrice = num * pharmacies.get(0).getSellingPrice();
        }


        //5. 查询患者是否开过当前处方
        CashierExample cashierExample = new CashierExample();
        CashierExample.Criteria cashierCriteria = cashierExample.createCriteria();
        cashierCriteria.andReportIdEqualTo(registerId);
        cashierCriteria.andDrugNameEqualTo(name);
        List<Cashier> cashiers = cashierMapper.selectByExample(cashierExample);
        Cashier cashier = new Cashier();

        //6. 开过修改，没开过，就添加
        if (cashiers == null || cashiers.size() == 0) {
            //添加
            cashier.setReportId(registerId);
            cashier.setDrugName(name);
            cashier.setDrugNum(num);
            cashier.setRepicePrice(pharmacies.get(0).getSellingPrice());
            cashier.setRepiceTotal(totalPrice);
            cashier.setState(0);
            cashier.setCtime(new Date());
            cashier.setMstate(0);
            count = cashierMapper.insertSelective(cashier);
            if (count != 1) {
                log.info("【添加处方失败】");
                throw new HospitalException(HospitalExceptionEnums.CAO_ADD_PRESCRIPTION);
            }
        } else {
            cashier = cashiers.get(0);
            //修改
            cashier.setDrugNum(cashier.getDrugNum() + num);
            cashier.setRepiceTotal(cashier.getRepiceTotal() + totalPrice);
            count = cashierMapper.updateByExampleSelective(cashier, cashierExample);
            if (count != 1) {
                log.info("【修改处方失败】");
                throw new HospitalException(HospitalExceptionEnums.CAO_ADD_PRESCRIPTION);
            }
        }
    }

    @Override
    public void addPrescription(CashierDTO cashierDTO) {
        Cashier cashier=new Cashier();
        cashier.setReportId(cashierDTO.getReportId());
        cashier.setDrugName(cashierDTO.getDrugname());
        cashier.setDrugNum(cashierDTO.getDrugnum());
        cashier.setRepicePrice(cashierDTO.getRepiceprice());
        cashier.setRepiceTotal(cashierDTO.getRepicetotal());
        cashier.setState(1);
        cashier.setOstate(cashierDTO.getOstate());
        cashier.setMstate(0);

        int count = cashierMapper.insertSelective(cashier);
        if (count!=1){
            log.info("【添加项目出纳】添加失败");
            throw new HospitalException(HospitalExceptionEnums.CAO_ADD_PRESCRIPTION);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public R deletePrescription(Integer id) {
        //查询是否已缴费
        Cashier cashier = cashierMapper.selectByPrimaryKey(id);
        if (cashier==null){
            return R.error(HospitalExceptionEnums.CAO_DELETE_PRESCRIPTION,"处方不存在!");
        }
        if (cashier.getMstate()!=0){
            return R.error(HospitalExceptionEnums.CAO_DELETE_PRESCRIPTION,"药品已缴费!");
        }

        //调用mapper
        Integer count = cashierMapper.deleteByPrimaryKey(id);
        if (count!=1){
            log.info("【删除处方】删除失败");
            return R.error(HospitalExceptionEnums.CAO_DELETE_PRESCRIPTION);
        }
        //增加库存
        return R.ok("删除药品成功！");
    }

    @Override
    public void updateChuProject(Integer reportId, String durgname, Integer durgnum) {
        //通过药名获得药品单价
        Double price=outPatientTypeService.findPriceByName(durgname);
        //计算购买药品的总价
        Double totalPrice=price*durgnum;
        //判断患者之前是否买过这种药     0为没买过，1为买过
        Cashier cashier=new Cashier();
        cashier.setReportId(reportId);
        cashier.setDrugName(durgname);
        cashier.setDrugNum(durgnum);
        cashier.setRepicePrice(price);
        cashier.setRepiceTotal(totalPrice);
        cashier.setState(1);
        cashier.setCtime(new Date());
        //判断该项目是否是需要做检查
        cashier.setOstate(outPatientTypeService.findOstateByName(durgname));
        cashier.setMstate(0);
        cashier.setJie("");
        //添加患者的出纳信息
        int insert = cashierMapper.insert(cashier);
        if (insert!=1){
            log.info("【患者的药品出纳信息添加失败】");
            throw new HospitalException(HospitalExceptionEnums.CAO_ADD_PRESCRIPTION);

        }
    }

    @Override
    public PageInfo<Cashier> findProjectByReportId(Integer perid, Integer page, Integer limit) {
        PageHelper.startPage(page,limit);
        List<Cashier> cashier = cashierMapper.selectProjectByReportId(perid);
        PageInfo<Cashier> pageInfo=new PageInfo<>(cashier);
        return pageInfo;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void remove(Integer id) {
        Cashier cashier = cashierMapper.selectByPrimaryKey(id);
        Integer drugNum = cashier.getDrugNum();
        String drugName = cashier.getDrugName();
        Integer mstate = cashier.getMstate();
        if (mstate==1){
            log.info("【患者的药品出纳信息删除】  患者的药品出纳信息已缴费无法删除");
            throw new HospitalException(HospitalExceptionEnums.CASHIER_DELETE_ERROR);
        }
        int i = cashierMapper.deleteByPrimaryKey(id);
        if (i!=1){
            log.info("【患者的药品出纳信息删除】  患者的药品出纳信息删除失败");
            throw new HospitalException(HospitalExceptionEnums.CASHIER_DELETE_ERROR);
        }
        if (cashier.getState()==0){
            pharmacyService.addNumByName(drugNum,drugName);
        }
    }

}
